import preprocess.Data2Feature as D2F
import preprocess.label_encode as Encode
import operator
import numpy as np
import pandas as pd
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import accuracy_score

NAME = 'Ridge'

class Fit:
    
    # ===========================================================================================================================================
    # Classifier: Ridge
    #     For more information about Ridge classifier, 
    #     please refer to http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html
    #
    # Input: X_train,Y_train,X_test,Y_test,CutMethod
    #
    # Output: predictions of X_test
    #
    # ================
    # Results:
    #
    # CutMethod == 'char':
    #     Ridge-char : Traning Set Accuracy: 0.986643
    #     Ridge-char : Test Set Accuracy: 0.834362
    # CutMethod == 'parse':
    #     Ridge-parse : Traning Set Accuracy: 0.990650
    #     Ridge-parse : Test Set Accuracy: 0.837449
    # ============================================================================================================================================
    
    # set params
    N1 = 3          # control the begining of all-grams of websites
    N2 = 7          # control the end of all-grams of websites
    Min_Web = 2       # feature minimum appeared times in whole dataset for website (url) information
    Min_Title = 1      # feature minimum appeared times in whole dataset for title information
    Title =True        # if Title == True: use title information to extract features
    Website = True       # if Website == True: use website (url) information to extract features
    Add = False          # if Add == True: count the number of features appeared in each data as input; else: only use 0-1
    Stopwords = True        # if Stopwords == True: remove stopwords such as punctuations
    alpha=1                # Regularization strength
    
    def __init__(self,X_train,Y_train,X_test,Y_test,CutMethod):
        self.predictions = self.fit(X_train,Y_train,X_test,Y_test,CutMethod)

    def fit(self,X_train,Y_train,X_test,Y_test,CutMethod):


        X = {}
        X['train'] = X_train
        X['test'] = X_test
        Y = {}
        Y['train'] = Y_train
        Y['test'] = Y_test
        
        # extract features from websites and titles
        X_features = D2F.Data2Feature(X,self.N1,self.N2,
                                      website=self.Website,
                                      title=self.Title,
                                      cutmethod=CutMethod,
                                      add=self.Add,
                                      stopwords=self.Stopwords, 
                                      min_web=self.Min_Web,
                                      min_title=self.Min_Title).features
        
        # encode string labels ('Art') to numbers (1)
        [Train_feature,Test_feature,Train_category,Test_category,le] = Encode.refomat(X_features,Y)
        
        # fit classifiers
        lin_clf = RidgeClassifier(alpha=self.alpha,random_state=0)
        lin_clf.fit(Train_feature, Train_category) 
        
        # predict
        Train_category_prediction = lin_clf.predict(Train_feature)
        print ('Ridge-%s : Traning Set Accuracy: %f' % (CutMethod,accuracy_score(Train_category,Train_category_prediction)))
        Test_category_prediction = lin_clf.predict(Test_feature)
        print ('Ridge-%s : Test Set Accuracy: %f' % (CutMethod,accuracy_score(Test_category,Test_category_prediction)))
        
        # decode labels for testset
        Y_test_prediction = le.inverse_transform(Test_category_prediction)

        return Y_test_prediction